package group2projman;

import java.util.ArrayList;
import java.util.LinkedList;

public class TransactionHistory {
	
	/// A transaction history's ID is that of its associated Member
	int memberId;
	
	LibrarySystem system;
	
	/// Ascending chronological order
	ArrayList<Transaction> transactions = new ArrayList<Transaction>();
	
	LinkedList<Loan> currentLoans = new LinkedList<Loan>();
	
	int currentFees = 0;
	
	public int getId() {		
		return memberId;		
	}
	
	public Loan[] getCurrentLoans() {
		return (Loan[])currentLoans.toArray();
	}
	
	public void addTransaction(Transaction transaction) {
		// TODO: validate?
		transactions.add(transaction);
		
		if (transaction.getType() == Transaction.Type.LOAN)
			currentLoans.add((Loan)transaction);
		else if (transaction.getType() == Transaction.Type.RETURN)
			handleReturn((Return)transaction);
		else if (transaction.getType() == Transaction.Type.RENEW)
			handleRenew((Renew)transaction);
		else if (transaction.getType() == Transaction.Type.DAMAGE_CHARGE)
			handleDamageCharge((DamageCharge)transaction);
		else if (transaction.getType() == Transaction.Type.PAYMENT)
			handlePayment((Payment)transaction);
	}
	
	private void handleReturn(Return bookReturn) {
		// Incur fee, if applicable
		currentFees += bookReturn.lateFee;
		
		// Search current loans for corresponding loan
		for (Loan loan : currentLoans)
			if (loan.bookCopyId == bookReturn.bookCopyId) {
				currentLoans.remove(loan);
				
				return;
			}
		// TODO: ensure renew replaces outstanding loan
		// Loan not found
		throw new RuntimeException("Book returned with no corresponding loan");
	}
	
	private void handleRenew(Renew renewal) {		
		// Search current loans for corresponding loan
		for (Loan loan : currentLoans)
			if (loan.bookCopyId == renewal.bookCopyId) {
				currentLoans.remove(loan);
				
				return;
			}
		// Loan not found
		throw new RuntimeException("Book renewal: loan not found");
	}
	
	private void handleDamageCharge(DamageCharge charge) {
		currentFees += charge.amount;
	}
	
	private void handlePayment(Payment payment) {
		currentFees -= payment.amount;
	}

}
